home *** CD-ROM | disk | FTP | other *** search
- /*
- * $RCSfile: callDisk.c,v $
- * $Revision: 1.1.1.1 $
- * $Date: 1996/05/04 21:55:40 $
- */
- /**********************************************************************
- * EXODUS Database Toolkit Software
- * Copyright (c) 1991 Computer Sciences Department, University of
- * Wisconsin -- Madison
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
- * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.
- * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
- * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * The EXODUS Project Group requests users of this software to return
- * any improvements or extensions that they make to:
- *
- * EXODUS Project Group
- * c/o David J. DeWitt and Michael J. Carey
- * Computer Sciences Department
- * University of Wisconsin -- Madison
- * Madison, WI 53706
- *
- * or exodus@cs.wisc.edu
- *
- * In addition, the EXODUS Project Group requests that users grant the
- * Computer Sciences Department rights to redistribute these changes.
- **********************************************************************/
- #include "mutex_compile.h"
-
- #include "sysdefs.h"
- #include "ess.h"
- #include "checking.h"
- #include "trace.h"
- #include "error.h"
- #include "list.h"
- #include "tid.h"
- #include "io.h"
- #include "lock.h"
- #include "object.h"
- #include "msgdefs.h"
- #include "disk.h"
- #include "thread.h"
- #include "semaphore.h"
- #include "latch.h"
- #include "link.h"
- #include "bf.h"
- #include "volume.h"
- #include "bitvec.h"
- #include "threadstate.h"
- #include "disk_funcs.h"
- #include "msg_funcs.h"
- #include "thread_globals.h"
- #include "stat_globals.h"
- #include "sharedmem_globals.h"
- #include "queue_consist.h"
-
-
- #ifdef TIME_CALLDISK
- #define HIST 50
- struct timeval hist[HIST];
- struct timeval avghist;
- int avgcount;
- static struct timezone timez;
- static int hist_index = 0;
-
- void
- btime(
- struct timeval *beginning
- )
- {
- if(gettimeofday(beginning, &timez)<0) {
- SM_ERROR(TYPE_FATAL ,errno);
- }
- }
-
- void
- etime(
- struct timeval *beginning
- )
- {
- struct timeval end, diff;
- register long usec;
-
- if(gettimeofday(&end, &timez)<0) {
- SM_ERROR(TYPE_FATAL ,errno);
- }
-
- usec = (end.tv_usec + 1000000) - beginning->tv_usec;
-
- if(usec>1000000) {
- usec -= 1000000;
- } else {
- end.tv_sec--;
- }
- diff.tv_usec = usec;
-
- diff.tv_sec = end.tv_sec - beginning->tv_sec;
-
- hist[hist_index].tv_sec = diff.tv_sec;
- hist[hist_index].tv_usec = diff.tv_usec;
- if(hist[hist_index].tv_usec >= 1000000) {
- hist[hist_index].tv_usec -= 1000000;
- hist[hist_index].tv_sec ++;
- }
- avghist.tv_sec += diff.tv_sec;
- avghist.tv_usec += diff.tv_usec;
- if(avghist.tv_usec >= 1000000) {
- avghist.tv_usec -= 1000000;
- avghist.tv_sec ++;
- }
- avgcount++;
- hist_index++;
- hist_index %= HIST;
- }
- #endif TIME_CALLDISK
-
- #include "queue_globals.h"
-
- int
- callDisk (
- VOLREC *volRec,
- DISKMSG *message
- )
- {
- #ifdef TIME_CALLDISK
- struct timeval beginning;
- #endif TIME_CALLDISK
-
- extern int serv_v_ops;
- extern int disk_requests;
- extern int disk_requests_out;
- extern int threads_awaiting_q;
- int blocked = 0; /* was, is blocked or will block */
- register LINK *diskLink = volRec->volLink;
-
- disk_requests++;
-
- if(fastPath(volRec, message)) {
- fast_path_taken++;
- return Active->error;
- }
- slow_path_taken++;
-
- {
- extern BOOL FastPathOnly;
- SM_ASSERT(LEVEL_1, (FastPathOnly == FALSE));
- }
- SM_ASSERT(LEVEL_1, (diskLink != NULL) );
-
- TRPRINT(TR_THREAD, TR_LEVEL_1,
- ("(Thread %d state %d) callDisk disk on vol %d",
- Active->id, Active->state, volRec->queues->semNum));
-
- TRPRINT(TR_DISK, TR_LEVEL_2, ("callDisk link %d", diskLink->id));
-
- #ifdef TIME_CALLDISK
- btime(&beginning);
- #endif TIME_CALLDISK
-
-
- /*
- * setup the thread id in the message to be used
- * to dispatch the waiting thread upon receipt
- */
- message->body.threadId = Active->id;
- message->diskmagic = DISK_MESSAGE_MAGIC;
-
- /*
- * send the message: we have two implementations:
- * 1 using shared-memory queues and the other using sockets.
- */
- /*
- * When using disk queues, we don't want stop-and-wait
- * behavior so we don't use the semaphore here.
- * Instead, we wait only if the disk queue is full.
- */
- getMutex(&(volRec->queues->toDisk.mutex));
- /*
- * Find out if the other process is blocked on a semaphore,
- * waiting for this queue to be non-empty. If so, we'll want to kick
- * the disk process before we're done but when we're out of this
- * critical section.
- */
- if(toDiskFull(volRec->queues)) {
- giveMutex(&(volRec->queues->toDisk.mutex));
- /*
- * ok, we can't put it on the queue yet, so put this thread
- * to sleep and run another
- * (This thread is awakened in selectDisk().)
- */
- threads_awaiting_q++;
-
- #define diskTakingRequests tcbList
- waitList( &(volRec->diskTakingRequests), THREAD_DISK_Q_WAIT );
- getMutex(&(volRec->queues->toDisk.mutex));
- }
-
- enq_to(volRec->queues, ShmAddressToOffset(message));
- blocked = volRec->queues->toDisk.mutex.willBlock;
- giveMutex(&(volRec->queues->toDisk.mutex));
-
- TRPRINT(TR_DISK|TR_DISKRW, TR_LEVEL_1,
- ("thread %d msgtype %d -> disk %d", Active->id,
- message->header.type, volRec->queues->semNum));
-
- if(blocked) {
- struct sembuf _sembuf;
-
- _sembuf.sem_num = volRec->queues->semNum;
- _sembuf.sem_op = 1; /* a semaphore V operation */
- _sembuf.sem_flg = 0;
- TRPRINT(TR_DISK|TR_DISKRW, TR_LEVEL_1,
- ("V on SYSV semaphore # %d", volRec->queues->semNum));
-
- serv_v_ops++;
- if( semop(SemId, &_sembuf, 1) < 0 ) {
- if(errno != EINTR) {
- SM_ERROR(TYPE_SYS, errno);
- }
- }
- }
- TRPRINT(TR_DISK|TR_THREAD, TR_LEVEL_1,
- ("waiting for disk %d to respond", volRec->queues->semNum));
-
-
- /*
- * wait on the list for completion of the request
- * (This thread is awakened in diskReceiveQ().)
- */
- disk_requests_out++;
-
- #define diskGivingResults diskLink->tcbList
- waitList( &(diskGivingResults), THREAD_DISK_WAIT );
-
- TRPRINT(TR_DISK|TR_THREAD, TR_LEVEL_1, ("call result:%d", Active->error));
-
- #ifdef TIME_CALLDISK
- etime(&beginning);
- #endif TIME_CALLDISK
-
- return(Active->error);
- }
-